#include "diary_interface.h"
#include "global_vars.h"
#include <sstream>
#include <iomanip>
#include <algorithm>

// URL解码函数
std::string urlDecode(const std::string& encoded) {
    std::string decoded;
    size_t len = encoded.length();
    
    for (size_t i = 0; i < len; i++) {
        if (encoded[i] == '%' && i + 2 < len) {
            // 获取十六进制字符
            std::string hex = encoded.substr(i + 1, 2);
            try {
                // 转换为字符
                unsigned char ch = static_cast<unsigned char>(std::stoi(hex, nullptr, 16));
                decoded += ch;
                i += 2; // 跳过已处理的字符
            } catch (const std::exception&) {
                // 如果转换失败，保留原字符
                decoded += encoded[i];
            }
        } else if (encoded[i] == '+') {
            // + 号代表空格
            decoded += ' ';
        } else {
            decoded += encoded[i];
        }
    }
    
    return decoded;
}

// SQLite 函数声明
extern "C" {
    int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int, void(*)(void*));
    sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
}

// 压缩相关实现
std::string DiaryInterface::compressContent(const std::string& content) {
    z_stream zs;
    memset(&zs, 0, sizeof(zs));
    
    if (deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK) {
        throw std::runtime_error("压缩初始化失败");
    }
    
    zs.next_in = (Bytef*)content.data();
    zs.avail_in = content.size();
    
    int ret;
    char outbuffer[32768];
    std::string outstring;
    
    do {
        zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
        zs.avail_out = sizeof(outbuffer);
        
        ret = deflate(&zs, Z_FINISH);
        
        if (outstring.size() < zs.total_out) {
            outstring.append(outbuffer, zs.total_out - outstring.size());
        }
    } while (ret == Z_OK);
    
    deflateEnd(&zs);
    
    if (ret != Z_STREAM_END) {
        throw std::runtime_error("压缩失败: " + std::to_string(ret));
    }
    
    return outstring;
}

std::string DiaryInterface::decompressContent(const std::string& compressed) {
    z_stream zs;
    memset(&zs, 0, sizeof(zs));
    
    if (inflateInit(&zs) != Z_OK) {
        throw std::runtime_error("解压初始化失败");
    }
    
    zs.next_in = (Bytef*)compressed.data();
    zs.avail_in = compressed.size();
    
    int ret;
    char outbuffer[32768];
    std::string outstring;
    
    do {
        zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
        zs.avail_out = sizeof(outbuffer);
        
        ret = inflate(&zs, 0);
        
        if (outstring.size() < zs.total_out) {
            outstring.append(outbuffer, zs.total_out - outstring.size());
        }
    } while (ret == Z_OK);
    
    inflateEnd(&zs);
    
    if (ret != Z_STREAM_END) {
        throw std::runtime_error("解压失败: " + std::to_string(ret));
    }
    
    return outstring;
}

// 创建新日记
bool DiaryInterface::createDiary(sqlite3* db, const std::string& title, const std::string& destination, 
                               const std::string& content, int user_id) {
    // 开始事务
    char* errMsg = nullptr;
    if (sqlite3_exec(db, "BEGIN TRANSACTION", nullptr, nullptr, &errMsg) != SQLITE_OK) {
        sqlite3_free(errMsg);
        return false;
    }

    try {
        // 压缩内容
        std::string compressed = compressContent(content);
        
        // 插入主表
        sqlite3_stmt* stmt;
        const char* sql = "INSERT INTO travel_diary (user_id, title, compressed_content, destination, views, average_rating) "
                         "VALUES (?, ?, ?, ?, 0, 3.0)";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            throw std::runtime_error("准备插入语句失败: " + std::string(sqlite3_errmsg(db)));
        }
        
        sqlite3_bind_int(stmt, 1, user_id);
        sqlite3_bind_text(stmt, 2, title.c_str(), -1, SQLITE_TRANSIENT);
        sqlite3_bind_blob(stmt, 3, compressed.data(), compressed.size(), SQLITE_TRANSIENT);
        sqlite3_bind_text(stmt, 4, destination.c_str(), -1, SQLITE_TRANSIENT);
        
        int result = sqlite3_step(stmt);
        sqlite3_finalize(stmt);
        
        if (result != SQLITE_DONE) {
            std::cerr << "插入日记失败: " << sqlite3_errmsg(db) << std::endl;
            return false;
        }
        
        sqlite3_int64 diary_id = sqlite3_last_insert_rowid(db);
        
        // 提交事务
        if (sqlite3_exec(db, "COMMIT", nullptr, nullptr, &errMsg) != SQLITE_OK) {
            sqlite3_free(errMsg);
            throw std::runtime_error("提交事务失败");
        }
        
        return true;
    } catch (const std::exception& e) {
        // 回滚事务
        sqlite3_exec(db, "ROLLBACK", nullptr, nullptr, nullptr);
        std::cerr << "创建日记失败: " << e.what() << std::endl;
        return false;
    }
}

// 获取用户的所有日记
std::vector<DiaryEntry> DiaryInterface::getUserDiaries(sqlite3* db, int user_id) {
    std::vector<DiaryEntry> diaries;
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT diary_id, user_id, title, compressed_content, destination, views, average_rating, created_at, updated_at "
                     "FROM travel_diary WHERE user_id = ? ORDER BY created_at DESC";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return diaries;
    }
    
    sqlite3_bind_int(stmt, 1, user_id);
    
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        DiaryEntry entry;
        entry.diary_id = sqlite3_column_int(stmt, 0);
        entry.user_id = sqlite3_column_int(stmt, 1);
        entry.username = getUsernameById(db, entry.user_id);  // 获取用户名
        entry.title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
        
        const void* blob = sqlite3_column_blob(stmt, 3);
        int blob_size = sqlite3_column_bytes(stmt, 3);
        std::string compressed(reinterpret_cast<const char*>(blob), blob_size);
        entry.content = decompressContent(compressed);
        
        entry.destination = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));
        entry.views = sqlite3_column_int(stmt, 5);
        entry.average_rating = sqlite3_column_double(stmt, 6);
        entry.created_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        entry.updated_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
        
        diaries.push_back(entry);
    }
    
    sqlite3_finalize(stmt);
    return diaries;
}

// 获取单篇日记
DiaryEntry DiaryInterface::getDiary(sqlite3* db, int diary_id) {
    DiaryEntry entry;
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT diary_id, user_id, title, compressed_content, destination, views, average_rating, created_at, updated_at "
                     "FROM travel_diary WHERE diary_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return entry;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        entry.diary_id = sqlite3_column_int(stmt, 0);
        entry.user_id = sqlite3_column_int(stmt, 1);
        entry.username = getUsernameById(db, entry.user_id);  // 获取用户名
        entry.title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
        
        const void* blob = sqlite3_column_blob(stmt, 3);
        int blob_size = sqlite3_column_bytes(stmt, 3);
        std::string compressed(reinterpret_cast<const char*>(blob), blob_size);
        entry.content = decompressContent(compressed);
        
        entry.destination = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));
        entry.views = sqlite3_column_int(stmt, 5);
        entry.average_rating = sqlite3_column_double(stmt, 6);
        entry.created_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
        entry.updated_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 8));
    }
    
    sqlite3_finalize(stmt);
    return entry;
}

// 更新日记
bool DiaryInterface::updateDiary(sqlite3* db, int diary_id, const std::string& title, 
                               const std::string& destination, const std::string& content) {
    std::string compressed = compressContent(content);
    
    sqlite3_stmt* stmt;
    const char* sql = "UPDATE travel_diary SET title = ?, compressed_content = ?, destination = ?, updated_at = CURRENT_TIMESTAMP "
                     "WHERE diary_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return false;
    }
    
    sqlite3_bind_text(stmt, 1, title.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_blob(stmt, 2, compressed.data(), compressed.size(), SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 3, destination.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_int(stmt, 4, diary_id);
    
    bool success = sqlite3_step(stmt) == SQLITE_DONE;
    sqlite3_finalize(stmt);
    
    return success;
}

// 删除日记
bool DiaryInterface::deleteDiary(sqlite3* db, int diary_id) {
    sqlite3_stmt* stmt;
    const char* sql = "DELETE FROM travel_diary WHERE diary_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return false;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    
    bool success = sqlite3_step(stmt) == SQLITE_DONE;
    sqlite3_finalize(stmt);
    
    return success;
}

// 增加浏览量
bool DiaryInterface::increaseViews(sqlite3* db, int diary_id) {
    sqlite3_stmt* stmt;
    const char* sql = "UPDATE travel_diary SET views = views + 1 WHERE diary_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return false;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    
    bool success = sqlite3_step(stmt) == SQLITE_DONE;
    sqlite3_finalize(stmt);
    
    return success;
}

// 评分相关实现
bool DiaryInterface::addRating(sqlite3* db, int diary_id, int user_id, double rating) {
    sqlite3_stmt* stmt;
    // 使用INSERT OR REPLACE允许更新已有评分
    const char* sql = "INSERT OR REPLACE INTO diary_rating (diary_id, user_id, rating, created_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP)";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return false;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    sqlite3_bind_int(stmt, 2, user_id);
    sqlite3_bind_double(stmt, 3, rating);
    
    bool success = sqlite3_step(stmt) == SQLITE_DONE;
    sqlite3_finalize(stmt);
    
    return success;
}

double DiaryInterface::getAverageRating(sqlite3* db, int diary_id) {
    double avg_rating = 0.0;
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT AVG(rating) FROM diary_rating WHERE diary_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return avg_rating;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        avg_rating = sqlite3_column_double(stmt, 0);
    }
    
    sqlite3_finalize(stmt);
    return avg_rating;
}

// 获取用户对特定日记的评分
double DiaryInterface::getUserRating(sqlite3* db, int diary_id, int user_id) {
    double user_rating = 0.0;
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT rating FROM diary_rating WHERE diary_id = ? AND user_id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return user_rating;
    }
    
    sqlite3_bind_int(stmt, 1, diary_id);
    sqlite3_bind_int(stmt, 2, user_id);
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        user_rating = sqlite3_column_double(stmt, 0);
    }
    
    sqlite3_finalize(stmt);
    return user_rating;
}

// 搜索相关实现
std::vector<DiaryEntry> DiaryInterface::searchByDestination(sqlite3* db, const std::string& destination, 
                                                         const std::string& sort_by, int page, int pageSize) {
    std::vector<DiaryEntry> diaries;
    
    // 计算偏移量
    int offset = (page - 1) * pageSize;
    
    // 构建SQL查询，直接在数据库层面进行排序和分页
    std::string sql = "SELECT diary_id FROM travel_diary WHERE LOWER(destination) LIKE LOWER(?) ";
    
    if (sort_by == "heat") {
        sql += "ORDER BY views DESC ";
    } else if (sort_by == "rating") {
        sql += "ORDER BY average_rating DESC ";
    } else if (sort_by == "time") {
        sql += "ORDER BY created_at DESC ";
    } else {
        sql += "ORDER BY views DESC ";  // 默认按热度排序
    }
    
    sql += "LIMIT ? OFFSET ?";
    
    sqlite3_stmt* stmt;
    if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
        return diaries;
    }
    
    // 添加通配符进行模糊匹配
    std::string searchPattern = "%" + destination + "%";
    sqlite3_bind_text(stmt, 1, searchPattern.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_int(stmt, 2, pageSize);
    sqlite3_bind_int(stmt, 3, offset);
    
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int diary_id = sqlite3_column_int(stmt, 0);
        diaries.push_back(getDiary(db, diary_id));
    }
    
    sqlite3_finalize(stmt);
    return diaries;
}

std::vector<DiaryEntry> DiaryInterface::fullTextSearch(sqlite3* db, const std::string& query, 
                                                     const std::string& sortBy, int page, int pageSize) {
    std::vector<DiaryEntry> diaries;
    std::vector<int> matched_diary_ids;
    
    // 计算偏移量
    int offset = (page - 1) * pageSize;
    
    sqlite3_stmt* stmt;
    // 获取所有日记数据进行内容匹配
    const char* sql = "SELECT diary_id, title, compressed_content, destination, views, average_rating, created_at "
                     "FROM travel_diary";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        std::cerr << "搜索准备失败: " << sqlite3_errmsg(db) << std::endl;
        return diaries;
    }
    
    std::string query_lower = query;
    std::transform(query_lower.begin(), query_lower.end(), query_lower.begin(), ::tolower);
    
    // 先收集所有匹配的日记ID和相关信息
    std::vector<std::tuple<int, int, double, std::string>> matched_entries; // diary_id, views, rating, created_at
    
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int diary_id = sqlite3_column_int(stmt, 0);
        std::string title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        std::string destination = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3));
        int views = sqlite3_column_int(stmt, 4);
        double rating = sqlite3_column_double(stmt, 5);
        std::string created_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6));
        
        // 检查标题是否匹配
        std::string title_lower = title;
        std::transform(title_lower.begin(), title_lower.end(), title_lower.begin(), ::tolower);
        bool title_match = title_lower.find(query_lower) != std::string::npos;
        
        // 检查目的地是否匹配
        std::string dest_lower = destination;
        std::transform(dest_lower.begin(), dest_lower.end(), dest_lower.begin(), ::tolower);
        bool dest_match = dest_lower.find(query_lower) != std::string::npos;
        
        // 检查内容是否匹配
        bool content_match = false;
        const void* blob = sqlite3_column_blob(stmt, 2);
        int blob_size = sqlite3_column_bytes(stmt, 2);
        if (blob && blob_size > 0) {
            try {
                std::string compressed(reinterpret_cast<const char*>(blob), blob_size);
                std::string content = decompressContent(compressed);
                
                std::string content_lower = content;
                std::transform(content_lower.begin(), content_lower.end(), content_lower.begin(), ::tolower);
                content_match = content_lower.find(query_lower) != std::string::npos;
            } catch (const std::exception& e) {
                std::cerr << "解压内容失败: " << e.what() << std::endl;
                content_match = false;
            }
        }
        
        // 如果匹配，加入结果
        if (title_match || dest_match || content_match) {
            matched_entries.push_back(std::make_tuple(diary_id, views, rating, created_at));
        }
    }
    
    sqlite3_finalize(stmt);
    
    // 根据排序参数进行排序
    if (sortBy == "heat") {
        std::sort(matched_entries.begin(), matched_entries.end(), 
            [](const auto& a, const auto& b) {
                return std::get<1>(a) > std::get<1>(b); // 按views排序
            });
    } else if (sortBy == "rating") {
        std::sort(matched_entries.begin(), matched_entries.end(), 
            [](const auto& a, const auto& b) {
                return std::get<2>(a) > std::get<2>(b); // 按rating排序
            });
    } else {
        std::sort(matched_entries.begin(), matched_entries.end(), 
            [](const auto& a, const auto& b) {
                return std::get<3>(a) > std::get<3>(b); // 按created_at排序
            });
    }
    
    // 应用分页
    int total_matches = matched_entries.size();
    int start_idx = std::min(offset, total_matches);
    int end_idx = std::min(offset + pageSize, total_matches);
    
    for (int i = start_idx; i < end_idx; i++) {
        int diary_id = std::get<0>(matched_entries[i]);
        DiaryEntry entry = getDiary(db, diary_id);
        if (entry.diary_id != 0) {
            diaries.push_back(entry);
        }
    }
    
    return diaries;
}

std::vector<DiaryEntry> DiaryInterface::recommendDiaries(sqlite3* db, int user_id, 
                                                      const std::string& interest, const std::string& sortBy,
                                                      int page, int pageSize) {
    std::vector<DiaryEntry> recommended_diaries;
    
    // 计算偏移量
    int offset = (page - 1) * pageSize;
    
    // 如果指定了简单排序方式，直接使用数据库排序和分页
    if (sortBy == "heat") {
        sqlite3_stmt* stmt;
        const char* sql = "SELECT diary_id FROM travel_diary ORDER BY views DESC LIMIT ? OFFSET ?";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            return recommended_diaries;
        }
        
        sqlite3_bind_int(stmt, 1, pageSize);
        sqlite3_bind_int(stmt, 2, offset);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int diary_id = sqlite3_column_int(stmt, 0);
            recommended_diaries.push_back(getDiary(db, diary_id));
        }
        
        sqlite3_finalize(stmt);
        return recommended_diaries;
        
    } else if (sortBy == "rating") {
        sqlite3_stmt* stmt;
        const char* sql = "SELECT diary_id FROM travel_diary ORDER BY average_rating DESC, views DESC LIMIT ? OFFSET ?";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            return recommended_diaries;
        }
        
        sqlite3_bind_int(stmt, 1, pageSize);
        sqlite3_bind_int(stmt, 2, offset);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int diary_id = sqlite3_column_int(stmt, 0);
            recommended_diaries.push_back(getDiary(db, diary_id));
        }
        
        sqlite3_finalize(stmt);
        return recommended_diaries;
        
    } else if (sortBy == "time") {
        sqlite3_stmt* stmt;
        const char* sql = "SELECT diary_id FROM travel_diary ORDER BY created_at DESC LIMIT ? OFFSET ?";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            return recommended_diaries;
        }
        
        sqlite3_bind_int(stmt, 1, pageSize);
        sqlite3_bind_int(stmt, 2, offset);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int diary_id = sqlite3_column_int(stmt, 0);
            recommended_diaries.push_back(getDiary(db, diary_id));
        }
        
        sqlite3_finalize(stmt);
        return recommended_diaries;
        
    } else {
        // 智能推荐算法 - 为了性能，我们优化策略
        // 对于大数据集，只处理最热门的N条记录进行智能推荐
        int candidate_limit = std::max(100, pageSize * 10); // 候选集大小
        
        sqlite3_stmt* stmt;
        const char* sql = "SELECT diary_id, user_id, title, compressed_content, destination, views, average_rating, created_at "
                         "FROM travel_diary ORDER BY (views * 0.6 + average_rating * 0.4) DESC LIMIT ?";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            return recommended_diaries;
        }
        
        sqlite3_bind_int(stmt, 1, candidate_limit);
        
        std::vector<std::tuple<int, double, std::string>> scored_candidates; // diary_id, score, created_at
        
        // 计算最大值用于归一化
        double max_views = 1.0;
        double max_rating = 5.0;
        
        // 先遍历一遍获取最大值
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int views = sqlite3_column_int(stmt, 5);
            double rating = sqlite3_column_double(stmt, 6);
            if (views > max_views) max_views = views;
            if (rating > max_rating) max_rating = rating;
        }
        
        // 重置查询
        sqlite3_reset(stmt);
        
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            int diary_id = sqlite3_column_int(stmt, 0);
            std::string title = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
            std::string destination = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 4));
            int views = sqlite3_column_int(stmt, 5);
            double rating = sqlite3_column_double(stmt, 6);
            std::string created_at = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 7));
            
            // 计算基础分数
            double score = (0.6 * (views / max_views)) + (0.4 * (rating / max_rating));
            
            // 兴趣匹配加成
            if (!interest.empty()) {
                std::string title_lower = title;
                std::string dest_lower = destination;
                std::string interest_lower = interest;
                
                std::transform(title_lower.begin(), title_lower.end(), title_lower.begin(), ::tolower);
                std::transform(dest_lower.begin(), dest_lower.end(), dest_lower.begin(), ::tolower);
                std::transform(interest_lower.begin(), interest_lower.end(), interest_lower.begin(), ::tolower);
                
                if (title_lower.find(interest_lower) != std::string::npos ||
                    dest_lower.find(interest_lower) != std::string::npos) {
                    score *= 2.0; // 兴趣匹配加成
                }
                
                // 内容匹配检查（仅对候选集进行，提高性能）
                const void* blob = sqlite3_column_blob(stmt, 3);
                int blob_size = sqlite3_column_bytes(stmt, 3);
                if (blob && blob_size > 0) {
                    try {
                        std::string compressed(reinterpret_cast<const char*>(blob), blob_size);
                        std::string content = decompressContent(compressed);
                        std::string content_lower = content;
                        std::transform(content_lower.begin(), content_lower.end(), content_lower.begin(), ::tolower);
                        
                        if (content_lower.find(interest_lower) != std::string::npos) {
                            score *= 1.5; // 内容匹配额外加成
                        }
                    } catch (const std::exception& e) {
                        // 解压失败，忽略内容匹配
                    }
                }
            }
            
            scored_candidates.push_back(std::make_tuple(diary_id, score, created_at));
        }
        
        sqlite3_finalize(stmt);
        
        // 按分数排序
        std::sort(scored_candidates.begin(), scored_candidates.end(),
            [](const auto& a, const auto& b) {
                return std::get<1>(a) > std::get<1>(b);
            });
        
        // 应用分页
        int total_candidates = scored_candidates.size();
        int start_idx = std::min(offset, total_candidates);
        int end_idx = std::min(offset + pageSize, total_candidates);
        
        for (int i = start_idx; i < end_idx; i++) {
            int diary_id = std::get<0>(scored_candidates[i]);
            DiaryEntry entry = getDiary(db, diary_id);
            if (entry.diary_id != 0) {
                recommended_diaries.push_back(entry);
            }
        }
    }
    
    return recommended_diaries;
}

// 路由设置实现
void DiaryInterface::setupDiaryRoutes(crow::SimpleApp& app, Database& db) {
    // 创建日记
    CROW_ROUTE(app, "/api/diary")
        .methods("POST"_method)
        ([&db](const crow::request& req) {
            auto x = crow::json::load(req.body);
            if (!x) return crow::response(400);
            
            std::string title = x["title"].s();
            std::string content = x["content"].s();
            std::string destination = x["destination"].s();
            int user_id = g_current_user_id;
            
            if (createDiary(db.get(), title, destination, content, user_id)) {
                return crow::response(200);
            }
            return crow::response(500);
        });
    
    // 获取用户日记列表
    CROW_ROUTE(app, "/api/diary/user/<int>")
        ([&db](int user_id) {
            auto diaries = getUserDiaries(db.get(), user_id);
            crow::json::wvalue result;
            result["diaries"] = crow::json::wvalue::list();
            
            for (size_t i = 0; i < diaries.size(); i++) {
                result["diaries"][i]["diary_id"] = diaries[i].diary_id;
                result["diaries"][i]["user_id"] = diaries[i].user_id;
                result["diaries"][i]["username"] = diaries[i].username;
                result["diaries"][i]["title"] = diaries[i].title;
                result["diaries"][i]["destination"] = diaries[i].destination;
                result["diaries"][i]["views"] = diaries[i].views;
                result["diaries"][i]["average_rating"] = diaries[i].average_rating;
                result["diaries"][i]["created_at"] = diaries[i].created_at;
            }
            
            return crow::response(result);
        });
    
    // 获取单个日记
    CROW_ROUTE(app, "/api/diary/<int>")
        ([&db](int diary_id) {
            auto diary = getDiary(db.get(), diary_id);
            if (diary.diary_id == 0) {
                return crow::response(404);
            }
            
            increaseViews(db.get(), diary_id);
            
            crow::json::wvalue result;
            result["diary_id"] = diary.diary_id;
            result["user_id"] = diary.user_id;
            result["username"] = diary.username;
            result["title"] = diary.title;
            result["content"] = diary.content;
            result["destination"] = diary.destination;
            result["views"] = diary.views;
            result["average_rating"] = diary.average_rating;
            result["created_at"] = diary.created_at;
            result["updated_at"] = diary.updated_at;
            
            return crow::response(result);
        });
    
    // 更新日记
    CROW_ROUTE(app, "/api/diary/<int>")
        .methods("PUT"_method)
        ([&db](const crow::request& req, int diary_id) {
            auto x = crow::json::load(req.body);
            if (!x) return crow::response(400);
            
            std::string title = x["title"].s();
            std::string content = x["content"].s();
            std::string destination = x["destination"].s();
            
            if (updateDiary(db.get(), diary_id, title, destination, content)) {
                return crow::response(200);
            }
            return crow::response(500);
        });
    
    // 删除日记
    CROW_ROUTE(app, "/api/diary/<int>")
        .methods("DELETE"_method)
        ([&db](int diary_id) {
            if (deleteDiary(db.get(), diary_id)) {
                return crow::response(200);
            }
            return crow::response(500);
        });
    
    // 添加评分
    CROW_ROUTE(app, "/api/diary/<int>/rate")
        .methods("POST"_method)
        ([&db](const crow::request& req, int diary_id) {
            auto x = crow::json::load(req.body);
            if (!x) return crow::response(400);
            
            int user_id = x["user_id"].i();
            double rating = x["rating"].d();
            
            if (addRating(db.get(), diary_id, user_id, rating)) {
                return crow::response(200);
            }
            return crow::response(500);
        });
    
    // 获取用户对日记的评分
    CROW_ROUTE(app, "/api/diary/<int>/rating/<int>")
        ([&db](int diary_id, int user_id) {
            double rating = getUserRating(db.get(), diary_id, user_id);
            
            crow::json::wvalue result;
            result["diary_id"] = diary_id;
            result["user_id"] = user_id;
            result["rating"] = rating;
            result["has_rated"] = (rating > 0);
            
            return crow::response(result);
        });
    
    // 按目的地搜索
    CROW_ROUTE(app, "/api/diary/search/destination/<string>")
        ([&db](const crow::request& req, const std::string& encoded_destination) {
            // URL解码目的地参数
            std::string destination = urlDecode(encoded_destination);
            
            // 获取查询参数
            auto params = req.url_params;
            std::string sortBy = params.get("sortBy") ? params.get("sortBy") : "heat";
            int page = params.get("page") ? std::stoi(params.get("page")) : 1;
            int pageSize = params.get("pageSize") ? std::stoi(params.get("pageSize")) : 9;
            
            auto diaries = searchByDestination(db.get(), destination, sortBy, page, pageSize);
            int totalCount = getSearchResultsCount(db.get(), destination, "destination");
            
            crow::json::wvalue result;
            result["diaries"] = crow::json::wvalue::list();
            result["pagination"]["currentPage"] = page;
            result["pagination"]["pageSize"] = pageSize;
            result["pagination"]["totalCount"] = totalCount;
            result["pagination"]["totalPages"] = (totalCount + pageSize - 1) / pageSize;
            result["pagination"]["hasNextPage"] = page < ((totalCount + pageSize - 1) / pageSize);
            result["pagination"]["hasPrevPage"] = page > 1;
            
            for (size_t i = 0; i < diaries.size(); i++) {
                result["diaries"][i]["diary_id"] = diaries[i].diary_id;
                result["diaries"][i]["user_id"] = diaries[i].user_id;
                result["diaries"][i]["username"] = diaries[i].username;
                result["diaries"][i]["title"] = diaries[i].title;
                result["diaries"][i]["destination"] = diaries[i].destination;
                result["diaries"][i]["views"] = diaries[i].views;
                result["diaries"][i]["average_rating"] = diaries[i].average_rating;
                result["diaries"][i]["created_at"] = diaries[i].created_at;
            }
            
            return crow::response(result);
        });
    
    // 全文搜索
    CROW_ROUTE(app, "/api/diary/search/text/<string>")
        ([&db](const crow::request& req, const std::string& encoded_query) {
            // URL解码搜索查询参数
            std::string query = urlDecode(encoded_query);
            
            // 获取查询参数
            auto params = req.url_params;
            std::string sortBy = params.get("sortBy") ? params.get("sortBy") : "heat";
            int page = params.get("page") ? std::stoi(params.get("page")) : 1;
            int pageSize = params.get("pageSize") ? std::stoi(params.get("pageSize")) : 9;
            
            auto diaries = fullTextSearch(db.get(), query, sortBy, page, pageSize);
            int totalCount = getSearchResultsCount(db.get(), query, "text");
            
            crow::json::wvalue result;
            result["diaries"] = crow::json::wvalue::list();
            result["pagination"]["currentPage"] = page;
            result["pagination"]["pageSize"] = pageSize;
            result["pagination"]["totalCount"] = totalCount;
            result["pagination"]["totalPages"] = (totalCount + pageSize - 1) / pageSize;
            result["pagination"]["hasNextPage"] = page < ((totalCount + pageSize - 1) / pageSize);
            result["pagination"]["hasPrevPage"] = page > 1;
            
            for (size_t i = 0; i < diaries.size(); i++) {
                result["diaries"][i]["diary_id"] = diaries[i].diary_id;
                result["diaries"][i]["user_id"] = diaries[i].user_id;
                result["diaries"][i]["username"] = diaries[i].username;
                result["diaries"][i]["title"] = diaries[i].title;
                result["diaries"][i]["destination"] = diaries[i].destination;
                result["diaries"][i]["views"] = diaries[i].views;
                result["diaries"][i]["average_rating"] = diaries[i].average_rating;
                result["diaries"][i]["created_at"] = diaries[i].created_at;
            }
            
            return crow::response(result);
        });
    
    // 推荐日记
    CROW_ROUTE(app, "/api/diary/recommend/<int>")
        ([&db](const crow::request& req, int user_id) {
            // 获取查询参数
            auto params = req.url_params;
            std::string sortBy = params.get("sortBy") ? params.get("sortBy") : "heat";
            std::string interest = params.get("interest") ? params.get("interest") : "";
            int page = params.get("page") ? std::stoi(params.get("page")) : 1;
            int pageSize = params.get("pageSize") ? std::stoi(params.get("pageSize")) : 9;
            
            auto diaries = recommendDiaries(db.get(), user_id, interest, sortBy, page, pageSize);
            int totalCount = getTotalDiariesCount(db.get());
            
            crow::json::wvalue result;
            result["diaries"] = crow::json::wvalue::list();
            result["pagination"]["currentPage"] = page;
            result["pagination"]["pageSize"] = pageSize;
            result["pagination"]["totalCount"] = totalCount;
            result["pagination"]["totalPages"] = (totalCount + pageSize - 1) / pageSize;
            result["pagination"]["hasNextPage"] = page < ((totalCount + pageSize - 1) / pageSize);
            result["pagination"]["hasPrevPage"] = page > 1;
            
            for (size_t i = 0; i < diaries.size(); i++) {
                result["diaries"][i]["diary_id"] = diaries[i].diary_id;
                result["diaries"][i]["user_id"] = diaries[i].user_id;
                result["diaries"][i]["username"] = diaries[i].username;
                result["diaries"][i]["title"] = diaries[i].title;
                result["diaries"][i]["destination"] = diaries[i].destination;
                result["diaries"][i]["views"] = diaries[i].views;
                result["diaries"][i]["average_rating"] = diaries[i].average_rating;
                result["diaries"][i]["created_at"] = diaries[i].created_at;
            }
            
            return crow::response(result);
        });
    
    // 调试路由：检查数据库状态
    CROW_ROUTE(app, "/api/diary/debug/status")
        ([&db]() {
            crow::json::wvalue result;
            
            sqlite3_stmt* stmt;
            const char* sql = "SELECT COUNT(*) FROM travel_diary";
            
            if (sqlite3_prepare_v2(db.get(), sql, -1, &stmt, nullptr) == SQLITE_OK) {
                if (sqlite3_step(stmt) == SQLITE_ROW) {
                    result["total_diaries"] = sqlite3_column_int(stmt, 0);
                }
                sqlite3_finalize(stmt);
            }
            
            // 获取前5个日记的基本信息
            const char* sql2 = "SELECT diary_id, title, destination FROM travel_diary LIMIT 5";
            if (sqlite3_prepare_v2(db.get(), sql2, -1, &stmt, nullptr) == SQLITE_OK) {
                result["sample_diaries"] = crow::json::wvalue::list();
                int index = 0;
                while (sqlite3_step(stmt) == SQLITE_ROW && index < 5) {
                    result["sample_diaries"][index]["diary_id"] = sqlite3_column_int(stmt, 0);
                    result["sample_diaries"][index]["title"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
                    result["sample_diaries"][index]["destination"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
                    index++;
                }
                sqlite3_finalize(stmt);
            }
            
            return crow::response(result);
        });
}

// 辅助方法实现
std::string DiaryInterface::getUsernameById(sqlite3* db, int user_id) {
    std::string username = "未知用户";
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT username FROM users WHERE id = ?";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return username;
    }
    
    sqlite3_bind_int(stmt, 1, user_id);
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        const char* usernameText = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
        if (usernameText) {
            username = std::string(usernameText);
        }
    }
    
    sqlite3_finalize(stmt);
    return username;
}

// 获取总数的辅助方法实现
int DiaryInterface::getTotalDiariesCount(sqlite3* db) {
    int count = 0;
    
    sqlite3_stmt* stmt;
    const char* sql = "SELECT COUNT(*) FROM travel_diary";
    
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        return count;
    }
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        count = sqlite3_column_int(stmt, 0);
    }
    
    sqlite3_finalize(stmt);
    return count;
}

int DiaryInterface::getSearchResultsCount(sqlite3* db, const std::string& query, const std::string& searchType) {
    int count = 0;
    
    if (searchType == "destination") {
        sqlite3_stmt* stmt;
        const char* sql = "SELECT COUNT(*) FROM travel_diary WHERE LOWER(destination) LIKE LOWER(?)";
        
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
            return count;
        }
        
        std::string searchPattern = "%" + query + "%";
        sqlite3_bind_text(stmt, 1, searchPattern.c_str(), -1, SQLITE_TRANSIENT);
        
        if (sqlite3_step(stmt) == SQLITE_ROW) {
            count = sqlite3_column_int(stmt, 0);
        }
        
        sqlite3_finalize(stmt);
    } else {
        // 对于全文搜索，需要遍历所有记录进行匹配（这里简化处理）
        count = getTotalDiariesCount(db); // 暂时返回总数，实际应用中可以优化
    }
    
    return count;
} 